﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace DotNETX.Utility
{
    public static class EncryptDecryptUtils
    {
        private static bool IsNullOrEmpty(string text)
        {
            if (!string.IsNullOrEmpty(text))
            {
                return string.IsNullOrEmpty(text.Trim());
            }
            return true;
        }

        #region DES

        public static string DESDecrypt(string encryptedText, string key, string iv = null)
        {
            byte[] bytesDESKey = Encoding.ASCII.GetBytes(key);
            byte[] bytesDESIV = null;
            if (!IsNullOrEmpty(iv))
            {
                bytesDESIV = Encoding.ASCII.GetBytes(iv);
            }
            return DESDecrypt(encryptedText, bytesDESKey, bytesDESIV);
        }

        public static string DESEncrypt(string strPlain, string key, string iv = null)
        {
            byte[] bytesDESKey = Encoding.ASCII.GetBytes(key);
            byte[] bytesDESIV = null;
            if (!IsNullOrEmpty(iv))
            {
                bytesDESIV = Encoding.ASCII.GetBytes(iv);
            }
            return DESEncrypt(strPlain, bytesDESKey, bytesDESIV);
        }

        public static string DESDecrypt(string encryptedText, byte[] key)
        {
            return DESDecrypt(encryptedText, key, key);
        }

        public static string DESDecrypt(string encryptedText, byte[] key, byte[] iv)
        {
            byte[] dataToDecrypt = Convert.FromBase64String(encryptedText);
            return Encoding.UTF8.GetString(DESDecryptData(dataToDecrypt, key, iv));
        }

        public static byte[] DESDecryptData(byte[] dataToDecrypt, byte[] key)
        {
            return DESDecryptData(dataToDecrypt, key, key);
        }

        public static byte[] DESDecryptData(byte[] dataToDecrypt, byte[] key, byte[] iv)
        {
            DESCryptoServiceProvider des = new DESCryptoServiceProvider
            {
                Key = key,
                IV = iv
            };
            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(dataToDecrypt, 0, dataToDecrypt.Length);
                    cs.FlushFinalBlock();
                }
                return ms.ToArray();
            }
        }

        public static string DESEncrypt(string plainText, byte[] key)
        {
            return DESEncrypt(plainText, key, key);
        }

        public static string DESEncrypt(string plainText, byte[] key, byte[] iv)
        {
            return Convert.ToBase64String(DESEncryptData(Encoding.UTF8.GetBytes(plainText), key, iv));
        }

        public static byte[] DESEncryptData(byte[] dataToEncrypt, byte[] key)
        {
            return DESEncryptData(dataToEncrypt, key, key);
        }

        public static byte[] DESEncryptData(byte[] dataToEncrypt, byte[] key, byte[] iv)
        {
            DESCryptoServiceProvider des = new DESCryptoServiceProvider
            {
                Key = key,
                IV = iv
            };
            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(dataToEncrypt, 0, dataToEncrypt.Length);
                    cs.FlushFinalBlock();
                }
                return ms.ToArray();
            }
        }

        #endregion

        #region Md5

        public static string MD5Encrption(string plainText)
        {
            if (IsNullOrEmpty(plainText))
            {
                throw new ArgumentNullException("加密字串为空");
            }
            byte[] original = Encoding.UTF8.GetBytes(plainText.Trim());
            return BitConverter.ToString(MD5EncrptionBytes(original, 0, original.Length)).ToUpperInvariant().Replace("-", string.Empty);
        }

        public static string MD5Encrption(string plainText, string salted)
        {
            return BitConverter.ToString(MD5EncrptionBytes(plainText, salted)).ToUpperInvariant().Replace("-", string.Empty);
        }

        public static byte[] MD5EncrptionBytes(string plainText, string salted)
        {
            if (IsNullOrEmpty(plainText))
            {
                throw new ArgumentNullException("加密字串为空");
            }
            if (IsNullOrEmpty(salted))
            {
                throw new ArgumentNullException("Salted字串为空");
            }
            byte[] original = Encoding.UTF8.GetBytes(plainText.Trim());
            byte[] saltValue = Encoding.UTF8.GetBytes(salted.Trim());
            byte[] toMd5 = new byte[original.Length + saltValue.Length];
            original.CopyTo(toMd5, 0);
            saltValue.CopyTo(toMd5, original.Length);
            return MD5EncrptionBytes(toMd5, 0, toMd5.Length);
        }

        public static byte[] MD5EncrptionBytes(byte[] toMd5, int offset, int count)
        {
            MD5 md5 = MD5.Create();
            byte[] saltPwd = md5.ComputeHash(toMd5, offset, count);
            Buffer.BlockCopy(md5.ComputeHash(saltPwd, 8, 8), 8, saltPwd, 8, 8);
            return saltPwd;
        }

        public static byte[] MD5Hash(string toMd5Text)
        {
            byte[] toMd5 = Encoding.UTF8.GetBytes(toMd5Text);
            return MD5.Create().ComputeHash(toMd5, 0, toMd5.Length);
        }

        public static byte[] MD5Hash(byte[] toMd5, int offset, int count)
        {
            return MD5.Create().ComputeHash(toMd5, offset, count);
        }

        #endregion
        ///// <summary>
        ///// DES加密方法
        ///// </summary>
        ///// <param name="strPlain">明文</param>
        ///// <param name="strDESKey">密钥</param>
        ///// <param name="strDESIV">向量</param>
        ///// <returns>密文</returns>
        //public static string DESEncrypt(string strPlain, string strDESKey, string strDESIV = null)
        //{
        //    if (string.IsNullOrEmpty(strDESIV)) strDESIV = strDESKey;
        //    //把密钥转换成字节数组
        //    byte[] bytesDESKey = ASCIIEncoding.ASCII.GetBytes(strDESKey);
        //    //把向量转换成字节数组
        //    byte[] bytesDESIV = ASCIIEncoding.ASCII.GetBytes(strDESIV);
        //    //声明1个新的DES对象
        //    DESCryptoServiceProvider desEncrypt = new DESCryptoServiceProvider();
        //    //开辟一块内存流
        //    MemoryStream msEncrypt = new MemoryStream();
        //    //把内存流对象包装成加密流对象
        //    CryptoStream csEncrypt = new CryptoStream(msEncrypt, desEncrypt.CreateEncryptor(bytesDESKey, bytesDESIV), CryptoStreamMode.Write);
        //    //把加密流对象包装成写入流对象
        //    StreamWriter swEncrypt = new StreamWriter(csEncrypt);
        //    //写入流对象写入明文
        //    swEncrypt.WriteLine(strPlain);
        //    //写入流关闭
        //    swEncrypt.Close();
        //    //加密流关闭
        //    csEncrypt.Close();
        //    //把内存流转换成字节数组，内存流现在已经是密文了
        //    byte[] bytesCipher = msEncrypt.ToArray();
        //    //内存流关闭
        //    msEncrypt.Close();
        //    //把密文字节数组转换为字符串，并返回
        //    return UnicodeEncoding.Unicode.GetString(bytesCipher);
        //}

        ///// <summary>
        ///// DES解密方法
        ///// </summary>
        ///// <param name="strCipher">密文</param>
        ///// <param name="strDESKey">密钥</param>
        ///// <param name="strDESIV">向量</param>
        ///// <returns>明文</returns>
        //public static string DESDecrypt(string strCipher, string strDESKey, string strDESIV = null)
        //{
        //    if (string.IsNullOrEmpty(strDESIV)) strDESIV = strDESKey;
        //    //把密钥转换成字节数组
        //    byte[] bytesDESKey = ASCIIEncoding.ASCII.GetBytes(strDESKey);
        //    //把向量转换成字节数组
        //    byte[] bytesDESIV = ASCIIEncoding.ASCII.GetBytes(strDESIV);
        //    //把密文转换成字节数组
        //    byte[] bytesCipher = UnicodeEncoding.Unicode.GetBytes(strCipher);
        //    //声明1个新的DES对象
        //    DESCryptoServiceProvider desDecrypt = new DESCryptoServiceProvider();
        //    //开辟一块内存流，并存放密文字节数组
        //    MemoryStream msDecrypt = new MemoryStream(bytesCipher);
        //    //把内存流对象包装成解密流对象
        //    CryptoStream csDecrypt = new CryptoStream(msDecrypt, desDecrypt.CreateDecryptor(bytesDESKey, bytesDESIV), CryptoStreamMode.Read);
        //    //把解密流对象包装成读出流对象
        //    StreamReader srDecrypt = new StreamReader(csDecrypt);
        //    //明文=读出流的读出内容
        //    string strPlainText = srDecrypt.ReadLine();
        //    //读出流关闭
        //    srDecrypt.Close();
        //    //解密流关闭
        //    csDecrypt.Close();
        //    //内存流关闭
        //    msDecrypt.Close();
        //    //返回明文
        //    return strPlainText;
        //}

    }
}
